package pumpkin.ast;

import pumpkin.evt.Environment;
import pumpkin.word.SymbolTxt;
import pumpkin.word.Token;
import pumpkin.word.TokenSource;
import pumpkin.word.TokenType;

/**
 * * E'->+TE'|e
 * 
 * @author jiang
 *
 */
public class Exprp implements Node {
	Texpr texpr = null;
	Exprp exprp = null;
	Epsilon epsilon = null;
	char symbol = 0;
	boolean useEpsilon = false;

	public char getOerator() {
		return symbol;
	}

	public void build(TokenSource tokenSource) {
		Token t = tokenSource.next();
		if (t.getType() == TokenType.SYMBOL) {
			if (SymbolTxt.Plus.getSymbol().equals(t.getText())) {
				symbol = '+';
				useEpsilon = false;
			} else if (SymbolTxt.Minus.getSymbol().equals(t.getText())) {
				symbol = '-';
				useEpsilon = false;
			} else {
				useEpsilon = true;
				epsilon = new Epsilon();
				tokenSource.pushBack(t);
			}
		} else {
			useEpsilon = true;
			epsilon = new Epsilon();
			tokenSource.pushBack(t);
		}
		if (!useEpsilon) {
			texpr = new Texpr();
			exprp = new Exprp();
			texpr.build(tokenSource);
			exprp.build(tokenSource);
		}
	}

	public Object excute(Environment env) {
		if (useEpsilon) {
			return null;
		}
		Object left_obj = texpr.excute(env);
		Object right_obj = exprp.excute(env);
		if (left_obj == null) {
			return right_obj;
		}
		if (right_obj == null) {
			return left_obj;
		}
		char c = exprp.getOerator();
		if (c == '+') {
			if (right_obj instanceof Double || left_obj instanceof Double) {
				return (Double.parseDouble(left_obj.toString()) + Double.parseDouble(right_obj.toString()));
			} else {
				return (Integer.parseInt(left_obj.toString()) + Integer.parseInt(right_obj.toString()));
			}
		} else if (c == '-') {
			if (right_obj instanceof Double || left_obj instanceof Double) {
				return (Double.parseDouble(left_obj.toString()) - Double.parseDouble(right_obj.toString()));
			} else {
				return (Integer.parseInt(left_obj.toString()) - Integer.parseInt(right_obj.toString()));
			}
		}
		return null;
	}
}
